'use strict';

const Controller = require('egg').Controller;

class ApplyController extends Controller {
	// 添加好友
	async addFriend(){
		const { ctx, app } = this
		// 当前用户id
		let current_user_id = ctx.authUser.id;
		// 验证参数
		ctx.validate({
			friend_id: {
					type: 'int',
					required: true,
					desc: '好友id'
			},
			nickname: {
					type: 'string',
					required: false,
					desc: '昵称'
			},
			lookme: {
					type: 'int',
					required: true,
					range: {
							in: [0, 1]
					},
					desc: '看我朋友圈权限'
			},
			lookhim: {
					type: 'int',
					range: {
							in: [0, 1]
					},
					required: true,
					desc: '是否看他朋友圈'
			},
		});
		let { friend_id, nickname, lookme, lookhim } = ctx.request.body;
		// 不能添加自己
		if(current_user_id == friend_id){
			ctx.throw(400, '不能添加自己');
		}
		// 对方是否存在
		let user = await app.model.User.findOne({
			where: { id: friend_id, status: 1 }
		})
		if(!user) ctx.throw(400, '用户不存在或被禁用！')
		// 之前是否申请过
		let apply = await app.model.Apply.findOne({
			 where: {
					user_id: current_user_id,
					friend_id,
					status: ['pending', 'agree']
			}
		})
		if(apply) ctx.throw(400, '你之前已经申请过了');
		// 创建申请
		apply = await app.model.Apply.create({
			user_id: current_user_id,
			friend_id,
			lookme,
			lookhim,
			nickname
		})
		if(!apply) ctx.throw(400, '申请失败');
		// 消息推送
		// if(app.ws.user && app.ws.user[friend_id]){
		// 	app.ws.user[friend_id].send(JSON.stringify({
		// 		msg:"updateApplyList"
		// 	}))
		// }
		ctx.send(friend_id, '', "updateApplyList")
		// 成功
		ctx.apiSuccess(apply);
	}

	// 获取好友申请列表
	async list() {
		const { ctx, app } = this;
		let current_user_id = ctx.authUser.id;
		// 当前页
		let page = ctx.params.page ? parseInt(ctx.params.page) : 1;
		// 每页记录数
		let limit = ctx.query.limit ? parseInt(ctx.query.limit) : 10;
		// 分页偏移量
		let offset = (page - 1) * limit;
		let rows = await app.model.Apply.findAll({
			// friend_id被申请用户，当前用户作为被申请用户
			where: {
				friend_id: current_user_id,
			},
			// 获取到申请表记录，关联用户表记录
			include: [{
				model: app.model.User,
				attributes: ['id', 'username', 'nickname', 'avatar']
			}],
			offset,
			limit,
			order: [
				['id', 'DESC']
			]
		});
		// 申请数量
		let count = await app.model.Apply.count({
			where: {
				friend_id: current_user_id,
				status: "pending"
			}
		});

		ctx.apiSuccess({
			rows, count
		});
	}

	// 处理好友申请
	async handle() {
		const { ctx, app } = this;
		let current_user_id = ctx.authUser.id;
		let id = parseInt(ctx.params.id)
		// 参数验证
		ctx.validate({
			nickname: {
				type: 'string',
				required: false,
				desc: '昵称'
			},
			status: {
				type: 'string',
				required: true,
				range: {
					in: ['refuse', 'agree', 'ignore']
				},
				desc: '处理结果'
			},
			lookme: {
				type: 'int',
				required: true,
				range: {
						in: [0, 1]
				},
				desc: '看我'
			},
			lookhim: {
				type: 'int',
				range: {
					in: [0, 1]
				},
				required: true,
				desc: '看他'
			},
		});
		
		// 查询该申请是否存在
		let apply = await app.model.Apply.findOne({
			where: {
				// 好友的申请，id为表id非用户id
				id: id,
				friend_id: current_user_id,
				status: "pending"
			},
			include: [{
				model: app.model.User
			}]
		});
		if (!apply) {
			ctx.throw(400, '该记录不存在');
		}
		// 处理了好友申请,如果本人也对该用户申请过,此申请也处理为同意
		let userApply = await app.model.Apply.findOne({
			where: {
				// 本人的申请
				user_id: apply.friend_id,
				friend_id: apply.user_id,
				status: "pending"
			}
		})
		let { status, nickname, lookme, lookhim } = ctx.request.body;
		let transaction;
		try {
			// 开启事务
			transaction = await app.model.transaction();

			// 设置该申请状态,传入事务
			await apply.update({ status }, { transaction });
			if(userApply && status == 'agree') await userApply.update({ status }, { transaction });
			
			// 同意的话，添加到好友列表中
			if (status == 'agree') {
				// 加入到对方好友列表
				await app.model.Friend.create({
					friend_id: current_user_id,
					user_id: apply.user_id,
					nickname: apply.nickname,
					lookme: apply.lookme,
					lookhim: apply.lookhim,
				}, { transaction });
				// 将对方加入到我的好友列表
				await app.model.Friend.create({
					friend_id: apply.user_id,
					user_id: current_user_id,
					nickname,
					lookme,
					lookhim,
				}, { transaction });
			}
			// 提交事务
			await transaction.commit();
			// 添加对方的朋友圈时间轴
			this.appendTimeLineMoment(apply.user_id, current_user_id)
			this.appendTimeLineMoment(current_user_id, apply.user_id)
			// 消息推送
			if (status == 'agree') {
				let message = {
					id: (new Date()).getTime(), 
					// 发送者头像
					from_avatar: ctx.authUser.avatar,
					// 发送者昵称
					from_name: apply.nickname || ctx.authUser.nickname || ctx.authUser.username, 
					// 发送者id
					from_id: current_user_id, 
					// 接收人/群 id
					to_id: apply.user_id, 
					// 接收人/群 名称
					to_name: nickname || apply.user.nickname || apply.user.username, 
					 // 接收人/群 头像
					to_avatar: apply.user.avatar,
					// 接收类型
					chat_type: 'user', 
					// 消息类型
					type: "system",
					// 消息内容
					data: "你们已经是好友，可以开始聊天啦",
					 // 其他参数
					options: {}, 
					// 创建时间
					create_time: (new Date()).getTime(), 
					// 是否撤回
					isremove: 0, 
				}
				// 推送给对方,
				ctx.sendAndSaveMessage(apply.user_id, { ...message });
				// message是引用传值,如果直接传message可能还没发送就被下面代码修改
				
				// 推送给自己
				message.from_avatar = apply.user.avatar;
				message.from_name = nickname || apply.user.nickname || apply.user.username;
				message.from_id = apply.user.id;

				message.to_avatar = ctx.authUser.avatar;
				message.to_name = apply.nickname || ctx.authUser.nickname || ctx.authUser.username;
				message.to_id = current_user_id;

				ctx.sendAndSaveMessage(current_user_id, { ...message });
				
			}
			
			return ctx.apiSuccess('操作成功');
			} catch (e) {
				// 事务回滚
				await transaction.rollback();
				return ctx.apiFail('操作失败');
		}
	}
	
	// 追加好友朋友圈时间轴
	async appendTimeLineMoment(friend_id, current_user_id){
		const { app, ctx } = this;
		// 拿到好友发布的朋友圈id
		let moments = await app.model.Moment.findAll({
			where: {
				user_id: friend_id
			},
			attributes: ['id', 'created_at','updated_at']
		});
		
		let data = moments.map(item => {
			return {
				user_id: current_user_id,
				moment_id: item.id,
				created_at: item.created_at,
				updated_at: item.updated_at,
				own: 0
			}
		})
		console.log(data)
		await app.model.MomentTimeline.bulkCreate(data)
	}
	
}

module.exports = ApplyController;
